package com.dandelion.manager.system.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.dandelion.commons.spring.SpringContextHolder;
import com.dandelion.commons.utils.BeanUtils;
import com.dandelion.commons.utils.StringUtils;
import com.dandelion.commons.web.model.AjaxResponse;
import com.dandelion.manager.system.domain.Resource;
import com.dandelion.manager.system.repository.ResourceMapper;
import com.dandelion.manager.system.service.ResourcePermitService;
import com.dandelion.manager.system.service.ResourceService;

@Service
public class ResourceServiceImpl implements ResourceService {
	
	@Autowired
	private ResourceMapper mapper ;
	
	@Autowired
	private ResourcePermitService resourcePermitService ;

	@CacheEvict(value="SystemResourceCache", allEntries=true)
	@Override
	public AjaxResponse add(Resource record) {
		AjaxResponse ajaxResponse = SpringContextHolder.getBean(AjaxResponse.class).reset() ;
		
		if(this.mapper.existsFileldValue(null, "text", record.getText()) > 0) 
			return AjaxResponse.failMsg("该名称已存在！") ;
		if(this.mapper.existsFileldValue(null, "identity", record.getIdentity()) > 0) 
			return AjaxResponse.failMsg("该权限标示已存在！") ;
		
		if(record.getPid() != null) {
			record.setMenu_id(null);
		}
		record.setSorting(this.mapper.nextSort(record.getPid(), record.getMenu_id()));
		this.mapper.insert(record) ;
		
		addPermit(record.getId(), record.getPermitIds());
		
		return ajaxResponse;
	}
	
	/**
	 * 添加权限
	 * @param resourceId
	 * @param permitIds
	 */
	private void addPermit(Long resourceId, String permitIds) {
		if(StringUtils.isNotBlank(permitIds)) {
			List<Long> permitIdsList = new ArrayList<Long>() ;
			String[] split = permitIds.split(",") ;
			for (String permitId : split) {
				permitIdsList.add(Long.parseLong(permitId));
			}
			this.resourcePermitService.insertBatch(resourceId, permitIdsList);
		}
	}

	@CacheEvict(value="SystemResourceCache", allEntries=true)
	@Override
	public AjaxResponse delete(Long id) {
		del(this.mapper.selectByPrimaryKey(id));
		return SpringContextHolder.getBean(AjaxResponse.class).reset() ;
	}
	
	@CacheEvict(value="SystemResourceCache", allEntries=true)
	public void del(Resource record) {
		//删除资源关联的权限
		this.resourcePermitService.deleteByResourceId(record.getId());
		
		List<Resource> rs = this.mapper.selectResourceListByPid(record.getId()) ;
		if(null != rs && !rs.isEmpty()) {
			for (Resource resource : rs) {
				del(resource);
			}
		}
		this.mapper.deleteByPrimaryKey(record.getId()) ;
	}

	@CacheEvict(value="SystemResourceCache", allEntries=true)
	@Override
	public AjaxResponse update(Resource record) {
		if(this.mapper.existsFileldValue(record.getId(), "text", record.getText()) > 0) 
			return AjaxResponse.failMsg("该名称已存在！") ;
		if(this.mapper.existsFileldValue(record.getId(), "identity", record.getIdentity()) > 0) 
			return AjaxResponse.failMsg("该权限标示已存在！") ;
		
		Resource resource = this.get(record.getId()) ;
		BeanUtils.copyNotNullProperties(record, resource);
		if(record.getPid() != null) {
			resource.setMenu_id(null);
		}
		this.mapper.updateByPrimaryKey(resource) ;
		
		//删除资源关联的权限
		this.resourcePermitService.deleteByResourceId(record.getId());
		addPermit(record.getId(), record.getPermitIds());
		
		return SpringContextHolder.getBean(AjaxResponse.class).reset() ;
	}

	@Cacheable(value="SystemResourceCache" ,key="#root.targetClass +\".\"+ #root.methodName + (\"(\"+#id+\")\")")
	@Override
	public Resource get(Long id) {
		return this.mapper.getResourceLinkPermit(id);
	}
	
	@Cacheable(value="SystemResourceCache" ,key="#root.targetClass +\".\"+ #root.methodName + (\"(\"+#menuId+\")\")")
	@Override
	public List<Resource> treegridByMenu(Long menuId) {
		List<Resource> tree = new ArrayList<Resource>() ;
		
		List<Resource> resouces = this.mapper.selectResourceListByMenuId(menuId) ;
		for (Resource resource : resouces) {
			tree.add(recursiveResource(resource)) ;
		}
		return tree;
	}
	
	@Cacheable(value="SystemResourceCache" ,key="#root.targetClass +\".\"+ #root.methodName + (\"(\"+#menuId+\")\")")
	@Override
	public List<Resource> treegridByMenuView(Long menuId) {
		List<Resource> tree = new ArrayList<Resource>() ;
		
		List<Resource> resouces = this.mapper.selectResourceListByMenuIdView(menuId) ;
		for (Resource resource : resouces) {
			tree.add(recursiveResource(resource)) ;
		}
		return tree;
	}
	
	@Cacheable(value="SystemResourceCache" ,key="#root.targetClass +\".\"+ #root.methodName + (\"(\"+#menuId+\")\")")
	@Override
	public List<Resource> treegridById(Long id) {
		List<Resource> tree = new ArrayList<Resource>() ;
		
		Resource resource = this.mapper.selectByPrimaryKey(id) ;
		tree.add(recursiveResource(resource)) ;
		
		return tree;
	}
	
	private Resource recursiveResource(Resource entity) {
		List<Resource> childs = this.mapper.selectResourceListByPid(entity.getId());
		if(null != childs && !childs.isEmpty()) {
			List<Resource> children = new ArrayList<Resource>() ;
			
			for (Resource r : childs) {
				if(null != r) {
					children.add(recursiveResource(r)); ;
				}
			}
			entity.setChildren(children);
		}
		return entity ;
	}

	@Cacheable(value="SystemResourceCache" ,key="#root.targetClass +\".\"+ #root.methodName + (\"(\"+#href+\")\")")
	@Override
	public Resource selectByHref(String href) {
		if(null != href && !"".equals(href.trim())) {
			return this.mapper.selectByHref(href);
		} 
		return null ;
	}

	@Override
	public Resource getResourceLinkPermit(Long id) {
		return this.mapper.getResourceLinkPermit(id);
	}

	//@Cacheable(value="SystemResourceCache" ,key="#root.targetClass +\".\"+ #root.methodName + (\"(\"+#menuId+\")\")")
	@Override
	public List<Resource> treegridByMenuLinkPermit(Long menuId) {
		List<Resource> tree = new ArrayList<Resource>() ;
		
		List<Resource> resouces = this.mapper.treegridByMenuLinkPermit(menuId) ;
		for (Resource resource : resouces) {
			tree.add(recursiveResource(resource)) ;
		}
		return tree;
	}
}
